/**
 * 主程序头文件
 * 
 * socket监听及线程池，以及逻辑处理，都写在此一个文件中。
 * 
 * @category   ZeroIm
 * @package    Main
 * @author     Xinze <superbighuang@hotmail.com>
 * @copyright  Copyright (c) 2006, 黄新泽
 * @version    1.0
 * @TODO       数据库连接，处理相关数据
 */

#include <iostream>
#include <map>
#include <string>
#include <string.h>
#include <sstream>
#include <fstream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>

#include <getopt.h>
#include "ConfigParser.h"  //获取配置文件用
#include "Log.h"           //获取日志
#include "String.h"        //获取字符串处理
#include "Date.h"          //获取字符串处理
//#include <log4cxx/logger.h>
//#include <log4cxx/propertyconfigurator.h>
//using namespace log4cxx;

using namespace std;

/**
 * 定义版本
 *
 * @var string
 */
#define VER "1.0.0"

/**
 * 失败返回值
 * 
 * @var int
 */
#define FAILED -1

/**
 * 接收信息最大长度
 * 
 * @var int
 */
#define MAXLINE 1024

/**
 * 是否调试
 * 
 * @var int
 */
#define DEBUG 1

/**
 * 数据分割符号
 * 
 * @var string
 */
#define DELIMITER string(" ")
#define DELIMITERC " "

/**
 * epoll最大连接数目
 * 
 * @var int
 */
#define OPEN_MAX 20000

/**
 * BACKLOG
 * 
 * @var int
 */
#define BACKLOG 10

/**
 * 线程池数量
 *
 * @var int
 */
#define THREAD_NUM 10

int start_num = 0;
int waken_num = THREAD_NUM;

/**
 * 读取ini配置文件类
 * 
 * @var ConfigParser
 */
ConfigParser ini("chat.cnf");

/**
 * 日志类
 * 
 * @var CLogger
 */
CLogger Logger;

//IM业务逻辑部分
//user_socket_map.erase(1);  删除USER_ID为1的值   int i=user_socket_map[1];取得用户1的socketid

//user_socket_map 用户socketid结构 USER_ID->SOCKETID
map<string, int> user_socket_map;

//user_kicktime_map 屏蔽用户->屏蔽时间结构 USER_ID->TIME
map<string, time_t> user_kicktime_map;

//map socket_user_map 用户uid结构 SOCKETID->USER_ID
map<int, string> socket_user_map;

//map socket_key_map 用户KEY MAP结构 fd->KEY   用来保存用户每次的key，来加密每次的消息
map<int, string> socket_key_map;

//用于生成CHANNEL ID和它下面所有连接的关联MAP  channelid->fd;
typedef std::multimap<string, int> channel_socket_map;
channel_socket_map group_socket_map;

//用于存放USER ID和他加入的频道ID的关联MAP  USER_ID->GID
typedef std::multimap<string, string> user_group_map;
user_group_map uid_gid_map;

/**
 * 监听端口
 *
 * @var int
 */
int ini_port;

/**
 * 踢掉用户时间
 *
 * @var int
 */
int kick_time;

string user_key, msg_key, admin_key, grp_list, ini_policy;

/**
 * 登录Key
 *
 * @var string
 */
string login_key;

/**
 * 线程池任务队列结构体
 * 
 * @var struct
 */
struct task
{
		int fd; //需要读写的文件描述符
		struct task *next; //下一个任务
};

/**
 * 用于读写两个的两个方面传递参数的结构体
 * 
 * @var struct
 */
struct user_data
{
		int fd;
		int tofd;
		string senddata;
};

/**
 * 声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
 * 
 * @var struct
 */
struct epoll_event ev, events[20];

/**
 * epoll_create
 * 
 * @var int
 */
int epfd;

/**
 * 线程互斥锁结构体
 * 
 * @var locker
 */
struct locker
{
		pthread_mutex_t mutex;
		pthread_cond_t cond;
} td;

struct task *readhead = NULL, *readtail = NULL, *writehead = NULL;

std::string& trim(std::string &);
void setnonblocking(int);

void group_socket_delete_one(string, int);
void user_group_delete_one(string, string);
void user_group_delete_one_All(string);
void notify_to_all_user(string);
void clear_socket_info(int);

string get_datetime();
string get_date();

string int2str(const int);

string get_log_name();
void handle_pipe(int);
void send_msg(int, string);

void *chat_task(void *args);
